﻿using Ribbon.Core.Event;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Ribbon.Core.Menu
{
    public class RibbonMenuSplitItem : RibbonMenuItem
    {
        public RibbonMenuSplitItem(string name)
            : base(name)
        {
            base.Height = 10;
        }
    }

    public class RibbonMenuItem
    {
        public RibbonMenuItem(string name)
        {
            this.name = name;

            this.text = name;

            this.font = Ribbon.DefaultFont;

            this.height = 25;

            this.backColor = Color.FromArgb(245, 245, 245);

            this.selectBackColor = Color.FromArgb(221, 221, 221);

            this.selectForeColor = Color.FromArgb(255, 255, 255);

            this.foreColor = Color.FromArgb(0, 0, 0);
        }

        /// <summary>
        /// text size
        /// </summary>
        private SizeF size;

        public SizeF Size
        {
            get { return size; }
            set { size = value; }
        }

        private bool isActive;

        public bool IsActive
        {
            get { return isActive; }
            set { isActive = value; }
        }

        private Color backColor;

        public Color BackColor
        {
            get { return backColor; }
            set { backColor = value; }
        }

        private Color foreColor;

        public Color ForeColor
        {
            get { return foreColor; }
            set { foreColor = value; }
        }

        private int height;

        public int Height
        {
            get { return height; }
            set { height = value; }
        }

        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private string text;

        public string Text
        {
            get { return text; }
            set { text = value; }
        }

        private Font font;

        public Font Font
        {
            get { return font; }
            set { font = value; }
        }

        private int lever;

        public int Lever
        {
            get { return lever; }
            set { lever = value; }
        }

        public Bitmap Image { get; set; }

        //public RibbonMenuItemCollection Items { get; set; }

        private Color selectBackColor;

        public Color SelectBackColor
        {
            get { return selectBackColor; }
            set { selectBackColor = value; }
        }

        private Color selectForeColor;

        public Color SelectForeColor
        {
            get { return selectForeColor; }
            set { selectForeColor = value; }
        }

        public event MouseClickDelegate MouseClick;

        public event MouseEnterDelegate MouseEnter;

        public event MouseMoveDelegate MouseMove;

        public event MouseLeaveDelegate MouseLeave;
         
        public void OnMouseDown(MouseEventArgs e)
        {
            if (MouseClick != null)
            {
                MouseClick(this, e);
            }
        }
    }

    public class RibbonMenuItemCollection : Control, IList<RibbonMenuItem>
    {
        private int imageSize = 18;

        private new Padding Margin = new Padding(5);

        private List<RibbonMenuItem> items;

        private RibbonMenuItem activeItem;

        private RibbonMenu parent;

        private System.Drawing.Graphics g;

        private BufferedGraphics buffer;


        public RibbonMenuItemCollection(RibbonMenu parent)
        {
            this.parent = parent;
            this.items = new List<RibbonMenuItem>();
            this.Width = 150;
            this.Height = 200;
            this.BackColor = Color.FromArgb(245, 245, 245);
            this.LostFocus += RibbonMenuItemCollection_LostFocus;

            this.Init();
        }

        ~RibbonMenuItemCollection()
        {
            if (g != null)
            {
                using (g)
                {
                    g = null;
                }
            }

            if (buffer != null)
            {
                using (buffer)
                {
                    buffer = null;
                }
            }
        }

        private void Init()
        {
            if (buffer == null)
            {
                BufferedGraphicsContext context = BufferedGraphicsManager.Current;

                int width = 0;
                int height = 0;

                foreach (Screen item in Screen.AllScreens)
                {
                    if (width < item.Bounds.Width)
                        width = item.Bounds.Width;
                    if (height < item.Bounds.Height)
                        height = item.Bounds.Height;
                }

                buffer = context.Allocate(this.CreateGraphics(), new Rectangle(0, 0, width, height));

                g = buffer.Graphics;

                g.SmoothingMode = SmoothingMode.AntiAlias;

                g.SmoothingMode = SmoothingMode.HighQuality;

                g.CompositingQuality = CompositingQuality.HighQuality;

                g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
            }
        }

        void RibbonMenuItemCollection_LostFocus(object sender, EventArgs e)
        {
            if (this.Parent != null)
            {
                this.Parent.Controls.Remove(this);
            }
        }

        public int IndexOf(RibbonMenuItem item)
        {
            throw new NotImplementedException();
        }

        public void Insert(int index, RibbonMenuItem item)
        {
            throw new NotImplementedException();
        }

        public void RemoveAt(int index)
        {
            throw new NotImplementedException();
        }

        public RibbonMenuItem this[int index]
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public void Add(RibbonMenuItem item)
        {
            this.items.Add(item);

            if (item.Size == SizeF.Empty)
            {
                item.Size = g.MeasureString(item.Text, item.Font);
            }
        }

        public void Clear()
        {
            throw new NotImplementedException();
        }

        public bool Contains(RibbonMenuItem item)
        {
            throw new NotImplementedException();
        }

        public void CopyTo(RibbonMenuItem[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public int Count
        {
            get { return items.Count; }
        }

        public bool IsReadOnly
        {
            get { throw new NotImplementedException(); }
        }

        public bool Remove(RibbonMenuItem item)
        {
            throw new NotImplementedException();
        }

        public IEnumerator<RibbonMenuItem> GetEnumerator()
        {
            return items.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return items.GetEnumerator();
        }

        bool show = false;

        internal bool Show(Control parent)
        {
            if (!show)
            {
                if (!parent.Controls.Contains(this))
                {
                    parent.Controls.Add(this);
                }

                this.Visible = true;

                this.BringToFront();

                this.Focus();

                show = true;
            }
            else
            {
                this.Visible = false;

                show = false;
            }

            return show;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            g.Clear(this.BackColor);

            using (Pen borderP = new Pen(Color.FromArgb(this.BackColor.R - 20, this.BackColor.R - 20, this.BackColor.R - 20)))
            {
                Rectangle border = new Rectangle(0, 0, this.Width - 1, this.Height - 1);

                g.DrawRectangle(borderP, border);
            }

            int height = 0;

            for (int i = 0; i < items.Count; i++)
            {
                var item = items[i];

                Rectangle rec = new Rectangle(this.Margin.Left, this.Margin.Top + height, this.Width - (this.Margin.Right + this.Margin.Left) - 1, item.Height);

                using (Brush backBru = new SolidBrush(item.IsActive ? item.SelectBackColor : item.BackColor))
                {
                    g.FillRectangle(backBru, rec);
                }

                if (item.Image != null)
                {
                    g.DrawImage(item.Image, new Rectangle(rec.X + 5, rec.Y + (rec.Height - imageSize) / 2, imageSize, imageSize));
                }

                if (item.Text != null && item.Text.Length > 0)
                {
                    Rectangle recText = new Rectangle(rec.X + imageSize + 15, (int)(rec.Y + (rec.Height - item.Size.Height) / 2), (int)(rec.Width - imageSize - 15), (int)(item.Size.Height));

                    using (Brush textBru = new SolidBrush(item.IsActive ? item.SelectForeColor : item.ForeColor))
                    {
                        g.DrawString(item.Text, item.Font, textBru, recText);
                    }
                }

                if (item is RibbonMenuSplitItem)
                {
                    using (Pen borderP = new Pen(Color.FromArgb(this.BackColor.R - 20, this.BackColor.R - 20, this.BackColor.R - 20)))
                    {

                    }
                }

                height += item.Height;
            }

            buffer.Render(e.Graphics);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if (activeItem != null)
            {
                activeItem.OnMouseDown(e);
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            int height = 0;

            RibbonMenuItem tempItem = null;

            for (int i = 0; i < items.Count; i++)
            {
                var item = items[i];

                Rectangle rec = new Rectangle(this.Margin.Left, this.Margin.Top + height, this.Width - (this.Margin.Right + this.Margin.Left) - 1, item.Height);

                if (e.Y >= this.Margin.Top + height && e.Y <= this.Margin.Top + height + item.Height)
                {
                    tempItem = item;

                    break;
                }

                height += item.Height;
            }

            if (tempItem != null)
            {
                if (activeItem != null)
                {
                    activeItem.IsActive = false;
                }

                tempItem.IsActive = true;

                activeItem = tempItem;

                this.Refresh();
            }
            else
            {
                if (activeItem != null)
                {
                    activeItem.IsActive = false;
                    activeItem = null;
                    this.Refresh();
                }
            }
        }

        protected override void OnLostFocus(EventArgs e)
        {
            if (this.Parent != null)
            {
                this.Refresh();

                this.Visible = false;

                if (activeItem != null)
                {
                    activeItem.IsActive = false;

                    activeItem = null;
                }

                show = false;
            }
        }
    }
}
